from django.shortcuts import render
from django_redis import get_redis_connection

# Create your views here.
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status
import pickle
import base64

from goods.models import SKU
from .serialziers import CartSerializer,CartSKUSerializer,CartDeleteSerializer,CartSelectAllSerializer
from . import constants


class CartView(APIView):
    #购物车增加
    def perform_authentication(self, request):
        #重写父类的用户验证方法，检验用户身份的方法
        pass
    #ｐｏｓｔ请求
    def post(self,request):
        #添加购物车
        serializer=CartSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        sku_id=serializer.validated_data.get('sku_id')
        count=serializer.validated_data.get('count')
        #状态
        selected = serializer.validated_data.get('selected')
        #尝试对请求的用户进行验证
        try:
            user=request.user
        except Exception:
            #验证失败　用户未登陆
            user=None

        if user is not None and user.is_authenticated:
            # 登陆用户 在redis　中保存
            redis_conn=get_redis_connection('cart')
            #链接管道
            pl=redis_conn.pipeline()
            #记录购物车商品数量redis 用户  商品　　　数量
            pl.hincrby('cart_%s' % user.id,sku_id,count)
            #记录购物车的勾选项
            if selected:
                #redis查询的字段　　用户　 商品
                pl.sadd('cart_selected_%s' % user.id,sku_id,)
            pl.execute()
            return Response(serializer.data,status=status.HTTP_201_CREATED)
        else:
            #用户未登陆在cookie中保存
            cart_str = request.COOKIES.get('cart')

            if cart_str:
                # 解析
                cart_str = cart_str.encode()  # str -> bytes
                cart_bytes = base64.b64decode(cart_str)  # b64decode(byes类型）
                cart_dict = pickle.loads(cart_bytes)
            else:
                cart_dict = {}
                # cart_dict = {
                #     sku_id_1: {
                #         'count': 10
                #         'selected': True
                #     },
                #     sku_id_2: {
                #         'count': 10
                #         'selected': False
                #     },
                #     sku_id_3: {
                #         'count': 10
                #         'selected': True
                #     }
                # }
            #如果商品在购物车中　累加
            if sku_id in cart_dict:
                cart_dict[sku_id]['count']+=count
                cart_dict[sku_id]['selected']=selected
            else:
                #如果商品不存在购物车　设置
                cart_dict[sku_id]={
                    'count':count,
                    'selected':selected
                }
            cart_cookie = base64.b64encode(pickle.dumps(cart_dict)).decode()
            #设置cookie
            response=Response(serializer.data)
            response.set_cookie('cart', cart_cookie, max_age=constants.CART_COOKIE_EXPIRES)
            return response
    #查询购物车
    def get(self,request):
        #判断用户是否登陆
        try:
            user=request.user
        except Exception:
            #验证失败　用户未登陆
            user=None

        if user is not None and user.is_authenticated:
            #用户已登陆
            #从redis中读取
            redis_conn=get_redis_connection('cart')
            #查询所有的用户指定的商品
            redis_cart=redis_conn.hgetall('cart_%s'% user.id)
            #查询每个商品的状态
            redis_cart_selected = redis_conn.smembers('cart_selected_%s' % user.id)
            cart={}
            #商品ｉｄ　数量　　遍历商品
            for sku_id,count in redis_cart.items():
                cart[int(sku_id)]={
                    'count':int(count),
                    #商品ｉｄ　的状态
                    'selected':sku_id in redis_cart_selected
                }
                # cart_dict = {
                #     sku_id_1: {
                #         'count': 10
                #         'selected': True
                #     },
                #     sku_id_2: {
                #         'count': 10
                #         'selected': False
                #     },
                #     sku_id_3: {
                #         'count': 10
                #         'selected': True
                #     }
        else:
            #用户未登陆　从cookie中取出
            cart=request.COOKIES.get('cart')
            print(cart)
            if cart is not None:
                                #ｐｙｔｈｏｎ　　　　　　解码　　　　　　编码
                cart = pickle.loads(base64.b64decode(cart.encode()))
                print(cart)
            else:
                cart={}
                # cart_dict = {
                #     sku_id_1: {
                #         'count': 10
                #         'selected': True
                #     },
                #     sku_id_2: {
                #         'count': 10
                #         'selected': False
                #     },
                #     sku_id_3: {
                #         'count': 10
                #         'selected': True
                #     }
        #遍历处理购物车数据
        #商品列表等于ｃａｒｔ的键
        # sku_id_list=cart.keys()
        #查询商品表　ｉｄ在sku_id_list中
        print(cart.keys())
        skus=SKU.objects.filter(id__in=cart.keys())
        print(skus)
        #遍历skus向ｓｋｕ对象添加count 和selected属性
        for sku in skus:
            sku.count=cart[sku.id]['count']
            sku.selected=cart[sku.id]['selected']
        serializer=CartSKUSerializer(skus,many=True)
        return Response(serializer.data)

    #修改购物车信息
    def put(self,request):
        serializer = CartSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        sku_id = serializer.validated_data.get('sku_id')
        count = serializer.validated_data.get('count')
        selected = serializer.validated_data.get('selected')

        #尝试对请求的用户进行验证
        try:
            user=request.user
        except Exception:
            #用户未登陆
            user=None
        if user is not None and user.is_authenticated:
            #用户已登陆在ｒｅｄｉｓ中保存
            redis_conn=get_redis_connection('cart')
            pl=redis_conn.pipeline()
            #这个用户修改{'count': 10'selected': True},数量
            pl.hset('cart_%s'% user.id,sku_id,count)
            if selected:
                #添加{'count': 10'selected': True},
                pl.sadd('cart_selected_%s'% user.id,sku_id)
            else:
                #删除{'count': 10'selected': True},
                pl.srem('cart_selected_%s'% user.id,sku_id)
            pl.execute()
            return Response(serializer.data)
        else:
            #用户未登陆
            cart=request.COOKIES.get('cart')
            if cart is not None:
                cart = pickle.loads(base64.b64decode(cart.encode()))
            else:
                cart={}

            cart[sku_id]={
                'count':count,
                'selected':selected
            }
            cookie_cart = base64.b64encode(pickle.dumps(cart)).decode()
            response = Response(serializer.data)
            # 设置购物车的cookie
            # 需要设置有效期，否则是临时cookie
            response.set_cookie('cart', cookie_cart, max_age=constants.CART_COOKIE_EXPIRES)
            return response

    #删除购物车的实现
    def delete(self,request):
        serializer=CartDeleteSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        sku_id=serializer.validated_data['sku_id']

        try:
            user = request.user
        except Exception:
            # 验证失败，用户未登录
            user = None
        #用户已登陆在ｒｅｄｉｓ中保存
        if user is not None and user.is_authenticated:
            redis_conn=get_redis_connection('cart')
            # print(redis_conn)
            #{16: {'selected': True, 'count': 1}
            #利用管道
            pl=redis_conn.pipeline()
            #ｈａｓｈ操作删除一个字段　
            pl.hdel('cart_%s'% user.id,sku_id)
            #ｓｅｔ操作删除selected字段　redis user sku
            pl.srem('cart_selected_%s'%user.id,sku_id)
            pl.execute()
            #删除成功　返回一个状态
            return Response(status=status.HTTP_204_NO_CONTENT)
        else:
            #用户未登陆 在cookie中保存
            response=Response(status=status.HTTP_204_NO_CONTENT)
            #使用ｐickle序列化购物车数据pickle操作的是bytes类型
            cart=request.COOKIES.get('cart')
            # cart_dict = {
            #     sku_id_1: {
            #         'count': 10
            #         'selected': True
            #     },
            #     sku_id_2: {
            #         'count': 10
            #         'selected': False
            #     },
            #     sku_id_3: {
            #         'count': 10
            #         'selected': True
            #     }
            if cart is not cart:
                #字典sku_id键
                cart = pickle.loads(base64.b64decode(cart.encode()))
                # print(cart)
                # cart[sku_id] = {
                #     'count': count,
                #     'selected': selected
                # }
                # 如果sku_id在ｃａｒｔ中删除sku_id
                if sku_id in cart:
                    del cart[sku_id]
                    cookie_cart = base64.b64encode(pickle.dumps(cart)).decode()
                    # 设置购物车的cookie
                    # 需要设置有效期，否则是临时cookie
                    response.set_cookie('cart', cookie_cart, max_age=constants.CART_COOKIE_EXPIRES)
            return response

#全选操作
class CartSelectAllView(APIView):
    #从写父类的用户验证方法　
    def perform_authentication(self, request):
        pass

    def put(self,request):
        serializer = CartSelectAllSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        selected=serializer.validated_data['selected']
        try:
            user = request.user
        except Exception:
            # 验证失败，用户未登录
            user = None
        #用户已登陆　在redis中保存
        if user is not None and user.is_authenticated:
            redis_conn=get_redis_connection('cart')
            cart=redis_conn.hgetall('cart_%s'% user.id,)
            sku_id_list=cart.keys()
            if selected:
                #全选
                redis_conn.sadd('cart_selected_%s'%user.id,*sku_id_list)
            else:
                #取消全选
                redis_conn.srem('cart_selected_%s' % user.id, *sku_id_list)
            return Response({'message':'ok'})
        else:
            #未登陆cookie中取出
            cart=request.COOKIES.get('cart')
            response=Response({'message':'ok'})

            if cart is not None:
                cart = pickle.loads(base64.b64decode(cart.encode()))
                for sku_id in cart:
                    cart[sku_id]['selected']=selected
                cookie_cart = base64.b64encode(pickle.dumps(cart)).decode()
                # 设置购物车的cookie
                # 需要设置有效期，否则是临时cookie
                response.set_cookie('cart',cookie_cart,max_age=constants.CART_COOKIE_EXPIRES)

            return response


